home *** CD-ROM | disk | FTP | other *** search
- ;* SEND.S
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Scheme code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Scoops: SEND and SELF *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: Amitabh Srivastava Date: 1986 *
- ;* Revision history: *
- ;* - 16 Jul 87: Lutz Euler *
- ;* Das Problem bei der Implementietrung von SEND ist das richtige *
- ;* Besetzen der fluid-Bindung von SELF. Jede Methode ist der Form *
- ;* (let ((self (fluid self))) ...) *
- ;* Durch SEND muss also SELF fluidig an das Objekt gebunden *
- ;* werden, an das die Nachricht geschickt wird. *
- ;* Die urspruengliche Version von SEND bzw. SEND-IF-HANDLES hat *
- ;* dieses nicht richtig implementiert. Daraufhin wurden folgende *
- ;* Aenderungen vorgenommen: *
- ;* - SEND und SEND-IF-HANDLES wurden so geaendert, dass die *
- ;* Argumente exakt in der Umgebung ausgewertet werden, in *
- ;* der man es erwartet. *
- ;* - Die fluid-Bindung von SELF erfolgt erst nach der *
- ;* Auswertung der Argumente. *
- ;* Dadurch wird sichergestellt, dass als Argumente auch SELF und *
- ;* direkte Aufrufe von Methoden der eigenen Klasse zulaessig sind. *
- ;************************************************************************
- ;* Beispiele: *
- ;* *
- ;* (send obj msg) *
- ;* expandiert zu *
- ;* ((lambda () *
- ;* (fluid-let ((self obj)) *
- ;* ((access msg (fluid self)))))) *
- ;* *
- ;* (send obj msg arg1 arg2) *
- ;* expandiert zu *
- ;* ((lambda (%%**%%0 %%**%%1) *
- ;* (fluid-let ((self obj)) *
- ;* ((access msg (fluid self)) %%**%%0 %%**%%1))) *
- ;* arg1 *
- ;* arg2) *
- ;************************************************************************
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- ;* There are two way to handle SEND. Unfortunately, they have an *
- ;* impact on the user syntax. *
- ;* *
- ;* 1. ``SEND obj msg args'' expands into something like *
- ;* (fluid-let ((SELF obj)) *
- ;* ((acess msg obj) args)) *
- ;* Each method expands into a *
- ;* (lambda (args) *
- ;* (let ((self (fluid self))) *
- ;* body)) *
- ;* One does not have to use the SEND form to invoke methods in *
- ;* the same class. They can be invoked as a Scheme function. *
- ;* This has the advantage of skipping over the overhead of a *
- ;* call to send; however, it has the disadvantage that send is no *
- ;* longer tail recursive. *
- ;* The version of SCOOPS for PCS uses this philosophy but by *
- ;* using some system dependant features we were able to make it *
- ;* tail recursive. *
- ;* *
- ;* 2. Another way is to have the SEND form pass an extra argument; *
- ;* for example, ``SEND obj msg args'' is expanded to *
- ;* ((access msg obj) obj args) *
- ;* Note: care should be taken so that OBJ not be evaluated more *
- ;* than once. *
- ;* Also, each method expects an extra argument: *
- ;* (lambda (SELF ,@bvl) body) *
- ;* With this approach the user has to use the SEND form to call *
- ;* any method (even methods in its class). *
- ;* *
- ;* I have changed the SCOOPS source as per 1 to use the existing *
- ;* SCOOPS syntax. It is a trivial change to make the sources conform *
- ;* to 2. *
- ;************************************************************************
-
- ; send
-
- (macro send
- (lambda (e)
- (let ((args (cdddr e))
- (msg (caddr e))
- (obj (cadr e)))
- ; Aenderung am 16.07.87 :
- ; Alt:
- ; `(LET ((SELF ,obj))
- ; (FLUID-LET ((SELF SELF))
- ; ((ACCESS ,msg SELF) ,@args)))
- ; Neu:
- (let ((formals
- (let loop ((rest args)
- (counter 0))
- (cond ((null? rest)
- #!null)
- (else
- (cons (string->symbol
- (string-append
- "%%**%%"
- (number->string counter '(int))))
- (loop (cdr rest) (1+ counter))))))))
- `((lambda ,formals
- (fluid-let ((self ,obj))
- ((access ,msg (fluid self)) ,@formals)))
- ,@args)))))
-
-
- ; send-if-handles
-
- (macro send-if-handles
- (lambda (e)
- (let ((obj (cadr e))
- (msg (caddr e))
- (args (cdddr e)))
- ; Aenderung am 16.07.87 :
- ; Alt:
- ; `(LET ((SELF ,obj))
- ; (IF (ASSQ ',msg (%SC-METHOD-STRUCTURE (ACCESS %SC-CLASS SELF)))
- ; (SEND SELF ,msg ,@args)
- ; #F))
- ; Neu:
- (let ((formals
- (let loop ((rest args)
- (counter 0))
- (cond ((null? rest)
- #!null)
- (else
- (cons (string->symbol
- (string-append
- "%%**%%"
- (number->string counter '(int))))
- (loop (cdr rest) (1+ counter))))))))
- `((lambda ,formals
- (fluid-let ((self ,obj))
- (if (assq ',msg (%sc-method-structure
- (access %sc-class (fluid self))))
- ((access ,msg (fluid self)) ,@formals)
- #F)))
- ,@args)))))
-